package com.hospital.dao.impl;

import com.hospital.model.Patient;
import com.hospital.util.DruidUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 患者数据访问对象
 * 处理与患者相关的数据库操作，包括查询、入院、出院、转床等功能
 */
public class PatientDao {
    
    /**
     * 从ResultSet中提取患者信息
     * @param rs ResultSet对象
     * @return 患者对象
     * @throws SQLException 如果数据库访问出错
     */
    private Patient extractPatientFromResultSet(ResultSet rs) throws SQLException {
        Patient patient = new Patient();
        patient.setPatientId(rs.getInt("patientId"));
        patient.setPatientName(rs.getString("patientName"));
        patient.setPatientGender(rs.getString("patientGender").charAt(0));
        patient.setPatientAge(rs.getInt("patientAge"));
        patient.setPatientPhone(rs.getString("patientPhone"));
        patient.setPatientIdCard(rs.getString("patientIdCard"));
        patient.setConditionDesc(rs.getString("conditionDesc"));
        patient.setDoctorId(rs.getString("doctorId"));
        return patient;
    }

    /**
     * 根据医生ID获取其负责的所有患者
     * @param doctorId 医生ID
     * @return 患者列表
     */
    public List<Patient> getPatientsByDoctorId(String doctorId) {
        List<Patient> patients = new ArrayList<>();
        String sql = "SELECT * FROM Patient WHERE doctorId = ?";
        
        try (Connection conn = DruidUtil.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            
            stmt.setString(1, doctorId);
            ResultSet rs = stmt.executeQuery();
            
            while (rs.next()) {
                patients.add(extractPatientFromResultSet(rs));
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        return patients;
    }
    
    /**
     * 根据医生ID和患者姓名模糊查询患者
     * @param doctorId 医生ID
     * @param patientName 患者姓名（支持模糊查询）
     * @return 匹配的患者列表
     */
    public List<Patient> searchPatientsByName(String doctorId, String patientName) {
        List<Patient> patients = new ArrayList<>();
        String sql = "SELECT * FROM Patient WHERE doctorId = ? AND patientName LIKE ?";
        
        try (Connection conn = DruidUtil.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            
            stmt.setString(1, doctorId);
            stmt.setString(2, "%" + patientName + "%");
            ResultSet rs = stmt.executeQuery();
            
            while (rs.next()) {
                patients.add(extractPatientFromResultSet(rs));
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        return patients;
    }
    
    /**
     * 获取患者详细信息，包括住院信息
     * @param patientId 患者ID
     * @return 包含患者基本信息和住院信息的Map
     */
    public Map<String, Object> getPatientDetail(Integer patientId) {
        Map<String, Object> patientDetail = new HashMap<>();
        
        // 获取病人基本信息
        String sql = "{CALL GetPatientDetails(?)}";
        
        try (Connection conn = DruidUtil.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql)) {
            
            stmt.setInt(1, patientId);
            ResultSet rs = stmt.executeQuery();
            
            if (rs.next()) {
                // 病人基本信息
                patientDetail.put("patientId", rs.getInt("patientId"));
                patientDetail.put("patientName", rs.getString("patientName"));
                patientDetail.put("patientGender", rs.getString("patientGender"));
                patientDetail.put("patientAge", rs.getInt("patientAge"));
                patientDetail.put("patientPhone", rs.getString("patientPhone"));
                patientDetail.put("conditionDesc", rs.getString("conditionDesc"));
                
                // 住院信息
                patientDetail.put("floorNum", rs.getInt("floorNum"));
                patientDetail.put("wardNum", rs.getString("wardNum"));
                patientDetail.put("bedNum", rs.getInt("bedNum"));
                patientDetail.put("date", rs.getString("beginTime"));
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        return patientDetail;
    }
    
    /**
     * 办理患者入院手续
     * @param patientName 患者姓名
     * @param patientGender 患者性别
     * @param patientAge 患者年龄
     * @param patientIdCard 患者身份证号
     * @param patientPhone 患者电话
     * @param conditionDesc 病情描述
     * @param doctorId 主治医生ID
     * @param bedId 病床ID
     * @return 入院手续是否办理成功
     * @throws SQLException 数据库操作异常
     */
    public boolean admitPatient(String patientName, char patientGender, int patientAge,
                              String patientIdCard, String patientPhone, String conditionDesc,
                              String doctorId, int bedId) throws SQLException {
        String sql = "{CALL admit_patient(?, ?, ?, ?, ?, ?, ?, ?)}";
        
        try (Connection conn = DruidUtil.getConnection();
             CallableStatement stmt = conn.prepareCall(sql)) {
            
            stmt.setString(1, patientName);
            stmt.setString(2, String.valueOf(patientGender));
            stmt.setInt(3, patientAge);
            stmt.setString(4, patientIdCard);
            stmt.setString(5, patientPhone);
            stmt.setString(6, conditionDesc);
            stmt.setString(7, doctorId);
            stmt.setInt(8, bedId);
            
            // 执行存储过程
            stmt.execute();
            return true;
            
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        }
    }
    
    /**
     * 办理患者出院手续
     * @param patientId 患者ID
     * @return 出院手续是否办理成功
     * @throws SQLException 数据库操作异常
     */
    public boolean dischargePatient(int patientId) throws SQLException {
        String sql = "{CALL delete_patient(?)}";
        
        try (Connection conn = DruidUtil.getConnection();
             CallableStatement stmt = conn.prepareCall(sql)) {
            
            stmt.setInt(1, patientId);
            stmt.execute();
            return true;
            
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        }
    }
    
    /**
     * 为患者更换病床
     * @param patientId 患者ID
     * @param newBedId 新病床ID
     * @return 换床是否成功
     * @throws SQLException 数据库操作异常
     */
    public boolean transferBed(int patientId, int newBedId) throws SQLException {
        String sql = "{CALL transfer_bed(?, ?)}";
        
        try (Connection conn = DruidUtil.getConnection();
             CallableStatement stmt = conn.prepareCall(sql)) {
            
            stmt.setInt(1, patientId);
            stmt.setInt(2, newBedId);
            stmt.execute();
            return true;
            
        } catch (SQLException e) {
            e.printStackTrace();
            throw e;
        }
    }
} 